#include <iostream>
#include <string>
#include <string.h>
#include <unistd.h>
using namespace std;

// pthread_create  pthread_join  pthread_cancel  pthread_self  pthread_exit  pthread_detach线程分离
// 测试pthread库的函数

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// const char* str5 = "hello 字符串常量区"; //即使是在全局创建，这个依然是常量区搞出来的地址
// void *modify_str(void *arg)
// {
//     pthread_mutex_lock(&mutex);

//     cout << (char *)arg << endl;
//     pthread_detach(pthread_self()); // 自己分离自己的时候要注意
//     cout << "线程 " << pthread_self() << " 修改字符串成功" << endl;
//     strcpy((char *)arg, "已被修改");
//     cout << (char *)arg << endl;

//     pthread_mutex_unlock(&mutex);

//     return nullptr;
// }

char str5[40] = "hello 已初始化全局数据区";
char str6[40]; // 未初始化全局数据区
const char *str7 = "hello 字符串常量";

// char* str8 = new char[20];//这是函数调用，函数调用要经过main函数才行，这是不可以的
char *str8 = new char[20];


void *modify_str_gobal(void *argc)
{
    // pthread_detach(pthread_self());
    strcpy(str5, "hello str5 已初始化全局数据区");
    strcpy(str6, "hello str6 未初始化全局数据区"); // 线程能看到全局区
    // cout << str7 << endl;

    // pthread_cancel(pthread_self()); // cancel也是需要回收的，cancel可以取消自己，但是一般是主线程取消其他线程的
    // cout << "我取消自己" << endl;    //线程被发送了取消信号不代表立马会被取消，这个取决于编译器，
    // int cnt = 10;                    //故为保证安全，要在join过后再执行其他代码，否则容易发生段错误
    // while (cnt--)
    // {
    //     sleep(1);
    //     cout << "我取消自己" << endl;
    // }


    // pthread_cancel((pthread_t)argc);
    // cout<<"我已取消了主线程"<<endl;//cancel可以取消主线程。这样主线程便不会执行，主线程的随着新线程的生命周期一起结束
    // sleep(2);

    // int *ret = new int(10);
    // cout << "我取消自己" << endl;

    // pthread_exit((void*)ret);//pthread_exit的退出信息也是可以被主线程join的，但是其不能返回自己的局部变量，否则报错
    // 可以返回堆变量，回到主线程要记得delete就行,也可以返回字符串常量的字符串
    // return (void *)ret;
    return nullptr;
}
int main()
{

    pthread_cancel(pthread_self());
    int cnt = 10;
    while(cnt--)
        cout<<"我已取消了主线程"<<endl;//故取消线程推荐在主函数取消其他线程，因为线程被发送取消信号后不一定立即取消，取决于编译器。
                                        //这样在主线程join过后在执行其他代码可以防止段错误
    // // 测试不同内存区域的值
    // char str1[] = "hello 栈";
    // const char *str2 = "hello 字符串常量区";
    // char *str3 = new char[10];
    // strcpy(str3, "hello 堆");
    // static char str4[] = "hello static";
    strcpy(str8, "hello 堆");

    pthread_t t1, t2, t3, t4, t5, t6;
    // pthread_create(&t1,nullptr,modify_str,(void*)str1);
    // pthread_create(&t2,nullptr,modify_str,(void*)str2);
    // pthread_create(&t3,nullptr,modify_str,(void*)str3);
    // pthread_create(&t4,nullptr,modify_str,(void*)str4);
    // pthread_create(&t5,nullptr,modify_str_gobal,nullptr);
    // pthread_create(&t6, nullptr, modify_str_gobal, (void *)pthread_self());

    // cout << "线程已经执行"<<endl;

    sleep(3);
    // cout<<endl;
    // cout<<str1<<endl;
    // cout<<str2<<endl;
    // cout<<str3<<endl;
    // cout<<str4<<endl;
    cout << str5 << endl;
    cout << str6 << endl;
    cout<<str8<<endl;

    // void *ret = nullptr;
    // int n = pthread_join(t6, &ret);
    // cout << "n: " << strerror(n) << endl; // 线程分离之后不能join了，否则join回失败，失败返回错误码
    // cout<<"ret: "<<*(int*)ret<<endl;
    // delete (int*)ret;

    // pthread_join(t6,nullptr);

    return 0;
}
